/*
 * Board.h
 *
 *  Created on: Mar 25, 2014
 *      Author: zby
 */

#ifndef BOARD_H_
#define BOARD_H_
#include "Graph.h"
//#include "Tests/Test_Board.h"
#include <math.h>
#include "FindAndUnion.h"


namespace board {
    //PLAYER_A ->o: W->E
    //PLAYER_B ->x: N->S
    typedef enum  {PLAYER_A, PLAYER_B, NONE} _eplayer;
    typedef unsigned int pos_X;
    typedef unsigned int pos_Y;

    class Board : public graph::Graph
    {
        //protected:
        public:
            const unsigned int size;
            bool put_move(pos_X x, pos_Y y, _eplayer eplayer);
            FindAndUnion fau_WE;
            FindAndUnion fau_SN;
        public:
            static const graph::EdgeVal EdgeInit;
            static const graph::EdgeVal EdgeConPlayer_A;
            static const graph::EdgeVal EdgeConPlayer_B;
            unsigned int GetBoardSize(void);

            Board(unsigned int size);
            Board(const Board &_b);
            virtual ~Board();

            //----My friends-----------------------------------------------------------:
            friend class Test_Board;
            friend ostream& operator<<(ostream& _stream,  Board &_board){
                using  std::cout;
                using  graph::Node;
                cout<<endl;
                //plot the columns number
                for(unsigned int i=0; i<_board.size; i++)
                    if(i==0) cout<<i;
                    else if(i<10) cout<<"  "<<i;
                    else cout<<" "<<i;
                cout<<endl<<" ";
                //plot the '_ _' sign
                for(unsigned int i=0; i<_board.size-1; i++) cout<<"_ _";
                cout<<"_ " <<endl;
                //plot rows
                for(Node i=0; i<_board.size; i++ ){
                    //alignment on the left side
                    for(int ii=i>9 ? 1:0; ii<static_cast<int>(i); ii++){
                        if(i<10) cout<<" ";
                        else cout<<" ";
                    }
                    cout<<i<<"\\";
                    //plot board contains
                    for(Node j=0; j<_board.size; j++ )
                    {
                        if( (board::PLAYER_A==_board.Get_node_value(i*_board.size+j)) && (j==(_board.size-1)) ) cout<<"x\\";
                        else if( (board::PLAYER_A==_board.Get_node_value(i*_board.size+j)) ) cout<<"x  ";
                        else if( (board::PLAYER_B==_board.Get_node_value(i*_board.size+j)) && (j==(_board.size-1)) ) cout<<"o\\";
                        else if( (board::PLAYER_B==_board.Get_node_value(i*_board.size+j)) ) cout<<"o  ";
                        else if( (board::NONE==_board.Get_node_value(i*_board.size+j)) && (j==(_board.size-1)) ) cout<<".\\";
                        else if( (board::NONE==_board.Get_node_value(i*_board.size+j)) ) cout<<".  ";
                    }
                    cout<<endl;
                }
                //plot bottom line '_ _'
                for(int i=0; i!=static_cast<int>(_board.size+1); i++) cout<<" ";
                cout<<"\\";
                for(unsigned int i=0; i<_board.size-1; i++) cout<<"_ _";
                    cout<<"_\\" <<endl;

                return _stream;
            }
            //-------------------------------------------------------------------------:
    };

}

#endif /* BOARD_H_ */


